845d9d0eed0f6556e11ee7f7204fda9c8dd41154,dx/src/com/android/dx/command/dexer/Main.java,Main,processAllFiles,#,468
Before Change
anyFilesProcessed = false;
String[] fileNames = args.fileNames;
if (args.numThreads > 1) {
threadPool = Executors.newFixedThreadPool(args.numThreads);
parallelProcessorFutures = new ArrayList<Future<Void>>();
}
try {
if (args.mainDexListFile != null) {
// with --main-dex-list
FileNameFilter mainPassFilter = args.strictNameCheck ? new MainDexListFilter() :
new BestEffortMainDexListFilter();
// forced in main dex
for (int i = 0; i < fileNames.length; i++) {
processOne(fileNames[i], mainPassFilter);
}
if (dexOutputArrays.size() > 0) {
throw new DexException("Too many classes in " + Arguments.MAIN_DEX_LIST_OPTION
+ ", main dex capacity exceeded");
}
if (args.minimalMainDex) {
// start second pass directly in a secondary dex file.
rotateDexFile();
}
// remaining files
for (int i = 0; i < fileNames.length; i++) {
processOne(fileNames[i], new NotFilter(mainPassFilter));
}
} else {
// without --main-dex-list
for (int i = 0; i < fileNames.length; i++) {
processOne(fileNames[i], ClassPathOpener.acceptAll);
}
}
} catch (StopProcessing ex) {
/*
* Ignore it and just let the error reporting do
* their things.
*/
}
if (args.numThreads > 1) {
try {
threadPool.shutdown();
if (!threadPool.awaitTermination(600L, TimeUnit.SECONDS)) {
throw new RuntimeException("Timed out waiting for threads.");
}
} catch (InterruptedException ex) {
threadPool.shutdownNow();
throw new RuntimeException("A thread has been interrupted.");
}
try {
for (Future<?> future : parallelProcessorFutures) {
future.get();
}
} catch (ExecutionException e) {
Throwable cause = e.getCause();
// All Exceptions should have been handled in the ParallelProcessor, only Errors
// should remain
if (cause instanceof Error) {
throw (Error) e.getCause();
} else {
throw new AssertionError(e.getCause());
}
} catch (InterruptedException e) {
// If we're here, it means all threads have completed cleanly, so there should not be
// any InterruptedException
throw new AssertionError(e);
}
}
After Change
String[] fileNames = args.fileNames;
// translate classes in parallel
classTranslatorPool = new ThreadPoolExecutor(args.numThreads,
args.numThreads, 0, TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(2 * args.numThreads, true),
new ThreadPoolExecutor.CallerRunsPolicy());
// collect translated and write to dex in order
classDefItemConsumer = Executors.newSingleThreadExecutor();
try {
if (args.mainDexListFile != null) {
// with --main-dex-list
FileNameFilter mainPassFilter = args.strictNameCheck ? new MainDexListFilter() :
new BestEffortMainDexListFilter();
// forced in main dex
for (int i = 0; i < fileNames.length; i++) {
processOne(fileNames[i], mainPassFilter);
}
if (dexOutputFutures.size() > 0) {
throw new DexException("Too many classes in " + Arguments.MAIN_DEX_LIST_OPTION
+ ", main dex capacity exceeded");
}
if (args.minimalMainDex) {
// start second pass directly in a secondary dex file.
// Wait for classes in progress to complete
synchronized(dexRotationLock) {
while(maxMethodIdsInProcess > 0 || maxFieldIdsInProcess > 0) {
try {
dexRotationLock.wait();
} catch(InterruptedException ex) {
/* ignore */
}
}
}
rotateDexFile();
}
// remaining files
for (int i = 0; i < fileNames.length; i++) {
processOne(fileNames[i], new NotFilter(mainPassFilter));
}
} else {
// without --main-dex-list
for (int i = 0; i < fileNames.length; i++) {
processOne(fileNames[i], ClassPathOpener.acceptAll);
}
}
} catch (StopProcessing ex) {
/*
* Ignore it and just let the error reporting do
* their things.
*/
}
try {
classTranslatorPool.shutdown();
classTranslatorPool.awaitTermination(600L, TimeUnit.SECONDS);
classDefItemConsumer.shutdown();
classDefItemConsumer.awaitTermination(600L, TimeUnit.SECONDS);
for (Future<Boolean> f : addToDexFutures) {
try {
f.get();
} catch(ExecutionException ex) {
// Catch any previously uncaught exceptions from
// class translation and adding to dex.
int count = errors.incrementAndGet();
if (count < 10) {
DxConsole.err.println("Uncaught translation error: " + ex.getCause());
} else {
throw new InterruptedException("Too many errors");
}
}
}